home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / imageman.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-25  |  11.3 KB  |  521 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992,1993
  4.  
  5.     imageman.c
  6.         Editing Image Manager(編集画像管理部)
  7.  
  8.     EIMnew            EIM の初期化
  9.     EIMdelete        EIM の終了
  10.  
  11.     EIMresize        編集画像のサイズの変更
  12.     EIMgetxbytes    編集画像バッファの1ラインのバイト数
  13.     EIMadrs            指定座標に対応する編集画像バッファのアドレス
  14.     EIMgetxsize        編集画像の大きさを得る
  15.     EIMgetysize        編集画像の大きさを得る
  16.     EIMdispon        画面表示も同時に行う
  17.     EIMdispoff        画面表示は行わない
  18.     
  19.     EIMpset            編集画像上に点を打つ
  20.     EIMline            直線を描く
  21.     EIMhline        水平直線を描く
  22.     EIMvline
  23.     EIMboxline        矩形(枠)を描く
  24.     EIMrboxline
  25.     EIMboxfill
  26.     EIMrboxfill        filled 矩形を描く
  27.     EIMgetblock        矩形イメージを切り出す
  28.     EIMputblock        矩形イメージを貼りつける
  29.     EIMpoint        指定した座標のカラーコード(パレット番号)を得る
  30.     EIMpoint_back    アンドゥーバッファ上のカラーコードを得る
  31.  
  32.     EIMgraypset
  33.     EIMgrayhline
  34.     EIMgrayhline_map
  35.  
  36.     EIMbackup        現在の編集画像をアンドゥーバッファに転送する
  37.     EIMloadbackup    アンドゥーバッファを現在の編集画像に
  38. */
  39.  
  40. #include <stdio.h>
  41. #include <malloc.h>
  42. #include <memory.h>
  43. #include <msdos.cf>
  44. #include <stdlib.h>
  45. #include "ge.h"
  46. #include "dispman.h"
  47. #include "imageman.h"
  48. #include "mask.h"
  49. #include "subgrp.h"
  50.  
  51.  
  52. int graycol(int col1, int col2, int rate)
  53. {
  54.     if(rate<0) rate=0; else if(rate>256) rate=256;
  55.     if(rate==0)
  56.         return col1;
  57.     if(rate==256)
  58.         return col2;
  59.     short r1,g1,b1, r2,g2,b2, r3,g3,b3;
  60.     r1 = (col1 >> 5) & 31;
  61.     g1 = (col1 >> 10) & 31;
  62.     b1 =  col1 & 31;
  63.     r2 = (col2 >> 5) & 31;
  64.     g2 = (col2 >> 10) & 31;
  65.     b2 =  col2 & 31;
  66.     short nr=256-rate;
  67.     r3 = ((r1 * nr + r2 * (short)rate + 128) >> 8);
  68.     g3 = ((g1 * nr + g2 * (short)rate + 128) >> 8);
  69.     b3 = ((b1 * nr + b2 * (short)rate + 128) >> 8);
  70.     if (r1==r3 && g1==g3 && b1==b3)
  71.     {
  72.         if (r2<r3) r3--; else if (r2>r3) r3++;
  73.         if (g2<g3) g3--; else if (g2>g3) g3++;
  74.         if (b2<b3) b3--; else if (b2>b3) b3++;
  75.     }
  76.     return (g3 << 10) + (r3 << 5) + b3;
  77. }
  78.  
  79.  
  80.  
  81. static    char    *eibuf = NULL, *eibufbak = NULL;
  82. static    int        xsize,ysize;
  83. static    int        xbytes;
  84. #define    IMAGE32K        0
  85. #define    IMAGE16            1
  86. static    int        imagetype;    // IMAGE32K, IMAGE16
  87. static    bool    dispsw;
  88.  
  89.  
  90. int EIMnew(int type, int xlen, int ylen)
  91. // type: 0=32Kcolors 1=16colors
  92. // xlen,ylen: 編集画像の大きさ(最小(320,240)(このときは1倍表示不可))
  93. {
  94.     eibuf = malloc(xlen*ylen*2);
  95.     eibufbak = malloc(xlen*ylen*2);
  96.     memset(eibuf,0,xlen*ylen*2);
  97.     memset(eibufbak,0,xlen*ylen*2);
  98.     xsize = xlen, ysize = ylen;
  99.     xbytes = xsize*2;
  100.     imagetype = IMAGE32K;
  101.     dispsw = YES;
  102.     return 0;
  103. }
  104.  
  105. void EIMdelete()
  106. {
  107. }
  108.  
  109.  
  110. int EIMresize(int xlen,int ylen)
  111. {
  112.     return 0;
  113. }
  114.  
  115. int EIMgetxbytes()
  116. {
  117.     return xbytes;
  118. }
  119.  
  120.  
  121. char *EIMadrs(int x,int y)
  122. {
  123.     if (imagetype == IMAGE32K)
  124.         return eibuf + xbytes*y + x*2;
  125.     else if (imagetype == IMAGE16)
  126.         return eibuf + xbytes*y + x/2;
  127. }
  128.  
  129. char *EIMadrs_back(int x,int y)
  130. {
  131.     if (imagetype == IMAGE32K)
  132.         return eibufbak + xbytes*y + x*2;
  133.     else if (imagetype == IMAGE16)
  134.         return eibufbak + xbytes*y + x/2;
  135. }
  136.  
  137. int    EIMgetxsize()
  138. {
  139.     return xsize;
  140. }
  141.  
  142. int EIMgetysize()
  143. {
  144.     return ysize;
  145. }
  146.  
  147.  
  148. void EIMdispon()
  149. {
  150.     dispsw = YES;
  151.     DMimage_refresh();
  152. }
  153.  
  154.  
  155. void EIMdispoff()
  156. {
  157.     dispsw = NO;
  158. }
  159.  
  160.  
  161. void EIMpset(int x, int y, int col, int op)
  162. {
  163.     if (x < 0 || xsize <= x || y < 0 || ysize <= y)
  164.         return;
  165.     if (mask_chkxy(x,y))
  166.         return;
  167.     if (op == DrawNORMAL)
  168.     {
  169.         *(unsigned short*)(eibuf + xbytes*y + x*2) = col;
  170.         if (dispsw)
  171.             DMimage_pset(x,y,col,DrawNORMAL);
  172.     }
  173.     else if (op == DrawXOR)
  174.     {
  175.         *(unsigned short*)(eibuf + xbytes*y + x*2) ^= col;
  176.         if (dispsw)
  177.             DMimage_pset(x,y,col,DrawXOR);
  178.     }
  179. }
  180.  
  181.  
  182. void EIMgraypset(int x,int y,int col,int gray)
  183. {
  184.     if (gray == 256)
  185.     {
  186.         EIMpset(x,y,col,DrawNORMAL);
  187.         return;
  188.     }
  189.     if (mask_chkxy(x,y))
  190.         return;
  191.     short *p = (short*)(eibuf + xbytes*y + x*2);
  192.     col = graycol(*p, col, gray);
  193.     *p = col;
  194.     if (dispsw)
  195.         DMimage_pset(x,y,col,DrawNORMAL);
  196. }
  197.  
  198. void EIMgrayhline(int x1,int x2,int y,int col,int gray,bool conc_sw)
  199. {
  200.     if (gray == 256)
  201.     {
  202.         EIMhline(x1,x2,y,col,DrawNORMAL);
  203.         return;
  204.     }
  205.     if (x1 > x2)
  206.         swap(x1,x2);
  207.     short *p0 = (short*)(eibuf + xbytes*y + x1*2);
  208.     if (!conc_sw || mixrate==256)
  209.     {
  210.         void hline(int _x1, int _x2, int _y)
  211.         {
  212.             short *p = p0 + _x1 - x1;
  213.             for (int i=_x1; i<=_x2; i++,p++)
  214.                 *p = graycol(*p, col, gray);
  215.         }
  216.         hline_func(x1,x2,y,hline);
  217.     }
  218.     else
  219.     {
  220.         short *back_p0 = (short*)(eibufbak + xbytes*y + x1*2);
  221.         char *cbufp;
  222.         int py = -1;
  223.         int mixr0 = getmixrate();
  224.         void hline(int _x1, int _x2, int _y)
  225.         {
  226.             if (_y != py)    // 濃度バッファ内でのアドレスの再計算の必要ありや?
  227.                 cbufp = cbuf_adrs(x1,_y), py=_y;
  228.             short *p=p0+_x1-x1, *bp=back_p0+_x1-x1;
  229.             for (int i=_x1; i<=_x2; i++,p++,bp++)
  230.             {
  231.                 int t = cbuf_mix(cbuf2conc(cbufp[i-x1]), gray, mixr0);
  232.                 cbufp[i-x1] = conc2cbuf(t);
  233.                 *p = mixcol(*bp,col,t,NO);
  234.                 if (*p==*bp)
  235.                 {
  236.                     int oc = mixcol(*bp,col,mixr0,NO);
  237.                     int r=getR(*p),g=getG(*p),b=getB(*p);
  238.                     if(r<getR(oc)) r++; else if(r>getR(oc)) r--;
  239.                     if(g<getG(oc)) g++; else if(g>getG(oc)) g--;
  240.                     if(b<getB(oc)) b++; else if(b>getB(oc)) b--;
  241.                     *p = r*32+g*1024+b;
  242.                 }
  243.             }
  244.         }
  245.         hline_func(x1,x2,y,hline);
  246.     }
  247.     if (dispsw)
  248.         DMimage_hline_map(x1,x2,y,(char*)p0);
  249. }
  250.  
  251. void EIMgrayhline_map(int x1,int x2,int y,int col,short int *graymap,
  252.                       bool conc_sw)
  253. {
  254.     if (x1 > x2)
  255.         swap(x1,x2);
  256.     short *p0      = (short*)(eibuf + xbytes*y + x1*2);
  257.     short *back_p0 = (short*)(eibufbak + xbytes*y + x1*2);
  258.     if (!conc_sw)
  259.     {
  260.         void hline(int _x1, int _x2, int _y)
  261.         {
  262.             short *p = p0 + _x1-x1, *gp = graymap + _x1-x1;
  263.             for (int i=_x1; i<=_x2; i++,p++,gp++)
  264.                 *p = (*gp==256?col:*gp==0?*p:graycol(*p, col, *gp));
  265.         }
  266.         hline_func(x1,x2,y,hline);
  267.     }
  268.     else
  269.     {
  270.         char *cbufp;
  271.         int py = -1;
  272.         int mixr0 = getmixrate();
  273.         void hline(int _x1, int _x2, int _y)
  274.         {
  275.             if (_y != py)    // 濃度バッファ内でのアドレスの再計算の必要ありや?
  276.                 cbufp = cbuf_adrs(x1,_y), py = _y;
  277.             short *p = p0 + _x1-x1, *bp = back_p0 + _x1-x1;
  278.             short *gp = graymap + _x1-x1;
  279.             for (int i=_x1; i<=_x2; i++,p++,bp++,gp++)
  280.             {
  281.                 if(*gp==0) continue;
  282.                 int t = cbuf_mix(cbuf2conc(cbufp[i-x1]), *gp, mixr0);
  283.                 cbufp[i-x1] = conc2cbuf(t);
  284.                 *p = mixcol(*bp,col,t,NO);
  285.                 if (*gp != 0 && *p == *bp)
  286.                 {
  287.                     int oc = mixcol(*bp,col,mixr0,NO);
  288.                     int r=getR(*p),g=getG(*p),b=getB(*p);
  289.                     if      (r<getR(oc))    r++;
  290.                     else if (r>getR(oc))    r--;
  291.                     if      (g<getG(oc))    g++;
  292.                     else if (g>getG(oc))    g--;
  293.                     if      (b<getB(oc))    b++;
  294.                     else if (b>getB(oc))    b--;
  295.                     *p = r*32+g*1024+b;
  296.                 }
  297.             }
  298.         }
  299.         hline_func(x1,x2,y,hline);
  300.     }
  301.     if (dispsw)
  302.         DMimage_hline_map(x1,x2,y,(char*)p0);
  303. }
  304.  
  305.  
  306. void EIMline(int x1,int y1,int x2,int y2,int col,int op)
  307. {
  308.     int x,y,xr,yr,r;
  309.     xr = abs(x2-x1);  yr = abs(y2-y1);
  310.     if (xr == 0 && yr == 0)
  311.         EIMpset(x1,y1,col,op);
  312.     else if (xr > yr)
  313.     {
  314.         r = (yr * 65536) / xr;
  315.         if (x2 < x1)
  316.             { swap(x1,x2);   swap(y1,y2); }
  317.         if (y1 > y2)
  318.             r = -r;
  319.         x2 = _min(x2,xsize-1);
  320.         for (x=x1,y=(y1<<16)+0x8000; x<=x2; x++,y+=r)
  321.             EIMpset(x,y>>16,col,op);
  322.     }
  323.     else
  324.     {
  325.         r = (xr << 16) / yr;
  326.         if (y2 < y1)
  327.             { swap(x1,x2); swap(y1,y2); }
  328.         if (x1 > x2)
  329.             r = -r;
  330.         y2 = _min(y2,ysize-1);
  331.         for (y=y1,x=(x1<<16)+0x8000; y<=y2; y++,x+=r)
  332.             EIMpset((x>>16),y,col,op);
  333.     }
  334. }
  335.  
  336.  
  337. void EIMhline(int x1,int x2,int y,int col,int op)    // 水平直線を描く
  338. {
  339.     if (x1>x2)
  340.         swap(x1,x2);
  341.     int ix = x1;
  342.     short *p = (short*)EIMadrs(x1,y);
  343.     void hline(int _x1,int _x2,int _y)
  344.     {
  345.         if (op == DrawXOR)
  346.             MEMstoreword_xor(getds(),(char*)(p+_x1-x1),col,(_x2-_x1+1));
  347.         else
  348.             MEMstoreword(getds(),(char*)(p+_x1-x1),col,(_x2-_x1+1));
  349.         if (dispsw)
  350.             DMimage_hline(_x1,_x2,_y,col,op);
  351.     }
  352.     hline_func(x1,x2,y,hline);
  353. }
  354.  
  355.  
  356. void EIMvline(int x,int y1,int y2,int col,int op)    // 垂直直線を描く
  357. {
  358.     if (y1>y2)
  359.         swap(y1,y2);
  360.     char *p = EIMadrs(x,y1);
  361.     int i;
  362.     if (op == DrawXOR)
  363.     {
  364.         int l = y2-y1+1;
  365.         for (i=0; i<l; i++,p+=xbytes)
  366.             if (!mask_chkxy(x,y1+i))
  367.                 { *(short*)p ^= col; if (dispsw) DMimage_pset(x,y1+i,col,op); }
  368.     }
  369.     else
  370.     {
  371.         int l = y2-y1+1;
  372.         for (i=0; i<l; i++,p+=xbytes)
  373.             if (!mask_chkxy(x,y1+i))
  374.                 { *(short*)p = col; if (dispsw) DMimage_pset(x,y1+i,col,op); }
  375.     }
  376.     //if (dispsw)
  377.     //    DMimage_vline(x,y1,y2,col,op);
  378. }
  379.  
  380.  
  381. void EIMboxline(int x1,int y1,int x2,int y2,int col,int op)    // 矩形(枠)を描く
  382. {
  383.     if (x1 > x2)
  384.         swap(x1,x2);
  385.     if (y1 > y2)
  386.         swap(y1,y2);
  387.     EIMhline(x1,x2,y1,col,op);
  388.     if (y2 > y1)
  389.         EIMhline(x1,x2,y2,col,op);
  390.     if (y2 > y1+1)
  391.         EIMvline(x1,y1+1,y2-1,col,op),  EIMvline(x2,y1+1,y2-1,col,op);
  392. }
  393.  
  394.  
  395. void EIMrboxline(int x,int y,int xlen,int ylen,int col,int op)    // 矩形(枠)を描く
  396. {
  397.     EIMboxline(x,y,x+xlen-1,y+ylen-1,col,op);
  398. }
  399.  
  400.  
  401. void EIMrboxfill(int x1,int y1,int xlen,int ylen,int col,int op)
  402. {
  403.     int i;
  404.     for (i=0; i<ylen; i++)
  405.         EIMhline(x1,x1+xlen-1,y1+i,col,op);
  406. }
  407.  
  408.  
  409. void EIMboxfill(int x1,int y1,int x2,int y2,int col,int op)
  410. {
  411.     if (x1 > x2)
  412.         swap(x1,x2);
  413.     if (y1 > y2)
  414.         swap(y1,y2);
  415.     EIMrboxfill(x1,y1,x2-x1+1,y2-y1+1,col,op);
  416. }
  417.  
  418.  
  419. int EIMpoint(int x,int y)
  420. {
  421.     if (x < 0 || y < 0 || xsize <= x || ysize <= y)
  422.         return backcol;
  423.     return (int)*(unsigned short*)(eibuf + xbytes*y + x*2);
  424. }
  425.  
  426.  
  427. int EIMpoint_back2(int x,int y)
  428. // x,y : 16ビット固定小数点
  429. {
  430.     if (x < 0 || y < 0 || xsize <= (x>>16) || ysize <= (y>>16))
  431.         return backcol;
  432.     char *ep = eibufbak + xbytes*(y>>16) + (x>>16)*2;
  433.     int px1,px2,py1,py2,w[4],c[4];
  434.     px2 = (x>>8)&0xff;  px1 = 256-px2;
  435.     py2 = (y>>8)&0xff;  py1 = 256-py2;
  436.     x>>=16,y>>=16;
  437.     w[0]=w[1]=w[2]=w[3]=0;
  438.     if (0<=y && y<ysize)
  439.     {
  440.         if (0<=x && x<xsize)
  441.             { if ((w[0] = (px1*py1+128)>>8) > 0)   c[0] = *(short*)ep; }
  442.         if (0<=x+1 && x+1<xsize)
  443.             { if ((w[1] = (px2*py1+128)>>8) > 0)   c[1] = *(short*)(ep+2); }
  444.     }
  445.     if (0<=y+1 && y+1<ysize)
  446.     {
  447.         if (0<=x && x<xsize)
  448.             { if ((w[2] = (px1*py2+128)>>8) > 0) c[2] = *(short*)(ep+xbytes); }
  449.         if (0<=x+1 && x+1<xsize)
  450.             { if ((w[3] = (px2*py2+128)>>8)>0) c[3] = *(short*)(ep+xbytes+2); }
  451.     }
  452.     int mag,rgb[3],i;
  453.     mag = 0, rgb[0]=rgb[1]=rgb[2]=0;
  454.     for (i=0; i<4; i++)
  455.     {
  456.         if (w[i] > 0)
  457.         {
  458.             int ci=c[i],wi=w[i];
  459.             mag+=wi;
  460.             rgb[0]+=getR(ci)*wi, rgb[1]+=getG(ci)*wi, rgb[2]+=getB(ci)*wi;
  461.         }
  462.     }
  463.     int h = mag/2;
  464.     return GRB((rgb[1]+h)/mag, (rgb[0]+h)/mag, (rgb[2]+h)/mag);
  465. }
  466.  
  467.  
  468. int EIMpoint_back(int x,int y)
  469. {
  470.     if (x < 0 || y < 0 || xsize <= x || ysize <= y)
  471.         return backcol;
  472.     return (int)*(unsigned short*)(eibufbak + xbytes*y + x*2);
  473. }
  474.  
  475.  
  476. void EIMgetblock(char *buf, int x,int y,int xlen,int ylen)
  477. {
  478.     int i;  char *p;
  479.     p = buf;
  480.     for (i=0; i<ylen; i++,p+=xlen*2)
  481.     {
  482.         // short *ep = (short*)EIMadrs(x,y+i);
  483.         // for (j=0; j<xlen; j++)
  484.         //     *(short*)(p+j*2) = *(ep+j);
  485.         memcpy(p, EIMadrs(x,y+i), xlen*2);
  486.     }
  487. }
  488.  
  489. void EIMputblock(int x,int y,int xlen,int ylen, char *buf, int op)
  490. {
  491.     int i; char *p;
  492.     p = buf;
  493.     for (i=0; i<ylen; i++,p+=xlen*2)
  494.     {
  495.         int yi = y+i;
  496.         if (yi < 0 || ysize <= yi)
  497.             continue;
  498.         int x1 = _max(x,0), x2 = _min(x+xlen-1,xsize-1);
  499.         short *pp = (short*)EIMadrs(x1,yi);
  500.         void hline(int _x1, int _x2, int _y)
  501.             { memcpy(pp + _x1-x1, p + (_x1-x)*2, (_x2-_x1+1)*2); }
  502.         hline_func(x1,x2,yi, hline);
  503.     }
  504.     if (dispsw)
  505.         DMimage_refresh();
  506. }
  507.  
  508.  
  509. void EIMbackup()        // 現在の編集画像をアンドゥーバッファに転送する
  510. {
  511.     memcpy(eibufbak, eibuf, xsize*ysize*2);
  512. }
  513.  
  514.  
  515. void EIMloadbackup()    // アンドゥーバッファを現在の編集画像に
  516. {
  517.     memcpy(eibuf, eibufbak, xsize*ysize*2);
  518.     if (dispsw)
  519.         DMimage_refresh();
  520. }
  521.